<?php
/*用户基础信息接口*/

namespace Usap\Service\Account;

use Usap\Service\Service;
use Think\Cache;

class user extends Service
{
    /**
     * 获取巡检员用户
     */
    public function getUserList()
    {
        return D("Usap/Account/user")->getField('user_id,user_name');
    }

    /**
     * 会员登录
     * @param string $account_name
     * @param string $password
     */
    public function login($account_name, $password)
    {

        if (empty($account_name)) {
            return $this->returnMsg('-1500');
        }

        if (empty($password)) {
            return $this->returnMsg('-1002');
        }
        $account_info = $this->searchAccount($account_name, array('user_id', 'user_name'));
        if (empty($account_info)) {
            return $this->returnMsg('-1200');
        }
        $check_info = $this->checkLoginPwd($account_info['user_id'], $password);
        if ($check_info['code'] != '0000') {
            return $check_info;
        }
        $cache_key = $account_info['access_token'];
        $cache_obj = Cache::singleton('redis');
        $cache_obj->set($cache_key, $account_info, 9999999999);//时间自定义
        return array('code' => '0000', 'msg' => '账户登录成功', 'user_data' => $account_info);
    }


    //退出登录
    public function logout($accessToken)
    {
        $cache_obj = Cache::singleton('redis');
        $cache_obj->rm($accessToken);
        return array('code' => '0000', 'msg' => '退出成功');
    }


    /**
     * 修改登录密码
     * @param int $user_id
     * @param int $new_pwd
     * @param string $old_pwd (md5后的)
     */
    public function modifyLoginPwd($user_id, $old_pwd, $new_pwd)
    {
        //校验用户
        $check_info = $this->checkIsVaild($user_id);
        if ($check_info['code'] != '0000') {
            return $check_info;
        }
        //校验原密码正确
        $user_info = $this->getInfoByID($user_id, array('user_password', 'reg_time'));
        $old_pwd = $this->genPasswd(md5($old_pwd), strtotime($user_info['reg_time']));
        if ($user_info['user_password'] != $old_pwd) {
            return $this->returnMsg('-1004');
        }
        //校验新旧密码
        $new_pwd = $this->genPasswd(md5($new_pwd), strtotime($user_info['reg_time']));
        if ($user_info['user_password'] == $new_pwd) {
            return $this->returnMsg('-1007');
        }
        //如果是后台用户
        if ($user_info['relationuid']) {
            $passwordinfo = array(
                'encrypt' => strtotime($user_info['reg_time']),
                'password' => $new_pwd,
                'is_modified' => 1,
            );
            $admin_optresult = D("Usap/Admin/Admin")->where("relationuid='$user_id'")->data($passwordinfo)->save();
            if ($admin_optresult === false) {
                return $this->returnMsg('-9999');
            }
        }

        $modify_result = D('Usap/Account/User')->where("user_id='$user_id'")->setField('user_password', $new_pwd);
        if ($modify_result === false) {

            return $this->returnMsg('-9999');
        }
        return array('code' => '0000', 'msg' => '密码修改成功');
    }


    /**
     * 根据手机号后6位初始化密码(默认为代理用户) md5(md5($inputpassword).$encrypt)
     * @param int $user_id
     */
    public function initLoginPwdByMobile($user_id)
    {
        $user_info = $this->getInfoByID($user_id, array('mobile', 'reg_time', 'user_password'));
        if (empty($user_info)) {
            $this->returnMsg('-1205');//用户名不存在
        }
        //判断user_info表中是否有手机号
        if (empty($user_info['mobile'])) {
            $this->returnMsg('-1911');//手机号码不存在
        }

        $new_loginpwd = $this->genPasswd(md5(substr($user_info['mobile'], -6)), strtotime($user_info['reg_time']));
        if ($new_loginpwd == $user_info['user_password']) {
            $this->returnMsg('-1912');//普通用户密码已经被初始化
        }

        //初始化user_info表中的密码
        $user_result = D('Usap/Account/User')->where(array('user_id' => $user_id))->data(array('user_password' => $new_loginpwd))->save();
        if ($user_result === false) {
            return $this->returnMsg('-9999');
        }
        return $this->returnMsg('0000');
    }


    /**
     * 根据新密码初始化密码 md5(md5($new_pwd).$encrypt)
     * @param int $user_id
     * @param string $new_pwd (md5后的)
     */
    public function initLoginPwdByNewPwd($user_id, $new_pwd)
    {
        $user_info = $this->getInfoByID($user_id, array('reg_time'));
        if (empty($user_info)) {
            $this->returnMsg('-1205');//用户名不存在
        }
        if (empty($new_pwd)) {
            $this->returnMsg('-1001');//新密码不能为空
        }
        //user_info用户信息变更
        $user_password = $this->genPasswd(md5($new_pwd), strtotime($user_info['reg_time']));

        //初始化user_info表中的密码
        $user_result = D('Usap/Account/User')->where(array('user_id' => $user_id))->data(array('user_password' => $user_password))->save();

        $admin_password = password($new_pwd);
        $data['password'] = $admin_password['password'];
        $data['encrypt'] = $admin_password['encrypt'];
        D("Usap/Admin/Admin")->where("relationuid='$user_id'")->data($data)->save();
        if ($user_result === false) {
            return $this->returnMsg('-9999');
        }
        return $this->returnMsg('0000');
    }


    /**
     * 修改用户信息
     * @param int $user_id 用户编号
     */
    public function modifyUserInfo($user_id, $data)
    {

        D("Usap/Admin/Admin")->where("relationuid='$user_id'")->data($data)->save();
        $modify_result = D('Usap/Account/User')->where("user_id='$user_id'")->data($data)->save();
        if ($modify_result === false) {
            return $this->returnMsg('-9999');
        }
        return array('code' => '0000', 'msg' => '手机号修改成功');
    }


    public function checkIsVaild($user_id)
    {

        $status_info = D('Usap/Account/User')->where("user_id=$user_id")->field(array('status'))->find();

        if (empty($status_info)) {
            return $this->returnMsg('-1200');
        }

        if ($status_info['status'] == 'Not') {
            return $this->returnMsg('-1201');
        }

        if ($status_info['status'] == 'Cancel') {
            return $this->returnMsg('-1202');
        }

        return $this->returnMsg('0000');
    }


    /**
     * @param string $user_id 账户编号
     * @param string $client_id 终端ID
     */
    public function cleanLoginLock($user_id, $client_id = -1)
    {

        if ($client_id != -1) $client_id = -1;

        $user_info = $this->getInfoByID($user_id, array('user_id'));
        if (empty($user_info['user_id'])) {
            return $this->returnMsg('-1200');
        }
        $user_id = $user_info['user_id'];
        $cache_key = 'service_user_checkloginpwd|user_id:' . $user_id;
        $cache_obj = Cache::singleton('redis');

        $cache_obj->rm($cache_key);
        return $this->returnMsg('0000');
    }


    /**
     * 根据账户名称查询账户信息
     * @param string $account_name (登录账户名)
     */
    public function searchAccount($login_account, $field_list = array())
    {

        $login_type = $this->getLoginTypeFromAccount($login_account);
        switch ($login_type) {

            case 'mobile':
                $account_info = $this->getInfoByMobile($login_account, $field_list);
                break;

            case 'user_name':
                $account_info = $this->getInfoByName($login_account, $field_list);
                break;

            default:
                $account_info = array();
                break;
        }
        //生成token
//        $accessType = C('API_FILTER_APP_LIST');
//        $func = 'process' . $accessType[0] . 'Login';
        $func = 'processUserAccesstokenLogin';
        $info = $this->$func($account_info);
        return $info;
    }

    /**
     * 校验登录密码(含加锁机制)
     * @param int $user_id 用户ID
     * @param string $input_pwd 输入的登录密码(md5加密后)
     * @param string $unique_lockid 加锁唯一ID
     */
    public function checkLoginPwd($user_id, $input_pwd)
    {
        if (empty($input_pwd)) {
            $this->returnMsg('-1001');
        }
        $user_info = $this->getInfoByID($user_id, array('user_password', 'reg_time'));
        if (empty($user_info)) {
            return $this->returnMsg('-1200');
        }
        $input_pwd = $this->genPasswd($input_pwd, strtotime($user_info['reg_time']));
        $cache_key = 'service_user_checkloginpwd|user_id:' . $user_id;
        $cache_obj = Cache::singleton('redis');
        $max_error_num = 4;//定义最大错误次数
        $max_error_hours = 3;//单位：小时
        $cache_val = $cache_obj->get($cache_key);
        if ($input_pwd != $user_info['user_password']) {
            $error_no = $cache_val['error_no'] + 1;
            $cache_obj->set($cache_key, array('error_no' => $error_no), $max_error_hours * 60 * 60);
            $last_no = $max_error_num - $cache_val['error_no'] - 1;
            if ($last_no <= 0) {
                return array('code' => '-1003', 'msg' => '密码错误, 请尝试找回密码！', 'last_time' => -1);

            } else {
                return array('code' => '-1002', 'msg' => '密码错误，请重试', 'last_time' => $last_no);
            }

        }
        return $this->returnMsg('0000');
    }


    public function processUserAccesstokenLogin($info)
    {
        $params['user_id'] = $info["user_id"];
        $params['user_name'] = $info["user_name"];
        try {
            $token = $this->createAccessToken($params);
        } catch (Exception $ex) {
            $log_info = array();
            $log_info['action'] = 'exception';
            $log_info['action_result'] = 'fail';
            $log_info['request'] = I();
            $log_info['exception'] = $ex;
            \Logger::getLogger('usap.user.user')->apps('login')->info(var_export($log_info, true));
            return array('isSucc' => 'N', 'ErrorMsg' => "temporarily_unavailable");
        }
        return $token;
    }


    public function createAccessToken($params = array())
    {
        $access_token = $this->genAccessToken();
        $result = [
            'user_id' => $params['user_id'],
            'user_name' => $params['user_name'],
            'access_token' => $access_token,
        ];
        return $result;
    }

    protected function genAccessToken()
    {
        $tokenLen = 40;
        if (function_exists('mcrypt_create_iv')) {
            $randomData = mcrypt_create_iv(100, MCRYPT_DEV_URANDOM);
        } else if (function_exists('openssl_random_pseudo_bytes')) {
            $randomData = openssl_random_pseudo_bytes(100);
        } else if (@file_exists('/dev/urandom')) { // Get 100 bytes of random data
            $randomData = file_get_contents('/dev/urandom', false, null, 0, 100) . uniqid(mt_rand(), true);
        } else {
            $randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);
        }
        return substr(hash('sha512', $randomData), 0, $tokenLen);
    }


    /**
     * 根据用户ID获取用户信息
     * @param int $user_id
     * @param array() $field_list
     */
    public function getInfoByID($user_id, $field_list = array())
    {

        if ($field_list) {
            $return_field = implode(',', $field_list);
            return D('Usap/Account/User')->where("user_id=$user_id")->field($return_field)->find();
        }
        return D('Usap/Account/User')->where("user_id=$user_id")->find();
    }

    /**
     * 生成密码
     * @param string $pass_wd (md5后的)
     * @param string $encrypt_salt
     */
    public function genPasswd($pass_wd, $encrypt_salt)
    {
        return md5($pass_wd . $encrypt_salt);
    }

    /**
     * 从账户获取登录方式
     * @param string $login_account
     * @return  string  $login_type
     */
    public function getLoginTypeFromAccount($login_account)
    {
        if (preg_match("/^1[0-9]{10}$/", $login_account)) {
            $login_type = 'mobile';
        } else {
            $login_type = 'user_name';
        }

        return $login_type;
    }


    /**
     * 根据手机号获取用户信息
     * @param int $mobile 手机号
     * @param array $field_list 返回列表信息
     */
    public function getInfoByMobile($mobile, $field_list = array())
    {
        $model = D('Usap/Account/User');
        if ($field_list) {
            $return_field = implode(',', $field_list);
            return $model->where("mobile='$mobile'")->field($return_field)->find();
        }
        return $model->where("mobile='$mobile'")->find();
    }


    /**
     * 根据用户名获取用户信息
     * @param string $user_name
     * @param string $field_list
     */
    public function getInfoByName($user_name, $field_list = array())
    {
        $model = D('Usap/Account/User');
        if ($field_list) {
            $return_field = implode(',', $field_list);
            return $model->where("user_name='$user_name'")->field($return_field)->find();
        }
        return $model->where("user_name='$user_name'")->find();
    }


    /**
     * 获取用户IP地址
     * @return string $client_ip
     */
    public function getUserIP()
    {

        if (getenv('HTTP_X_FORWARDED_IP')) {
            $client_ip = getenv('HTTP_X_FORWARDED_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
            $client_ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('HTTP_X_CLUSTER_CLIENT_IP')) {
            $client_ip = getenv('HTTP_X_CLUSTER_CLIENT_IP');
        } elseif (getenv('REMOTE_ADDR')) {
            $client_ip = getenv('REMOTE_ADDR');
        } else {
            $client_ip = $HTTP_SERVER_VARS['REMOTE_ADDR'];
        }
        return $client_ip;
    }


    public function returnMsg($code)
    {

        $cfg = array(

            /*-0001系统参数校验*/

            /*-1000登录密码校验*/
            '-1001' => '密码输入不能为空，请重新填写',
            '-1002' => '输入登录密码有误，请重新填写',
            '-1003' => '输入登录密码超过最大次数，请重新填写',
            '-1004' => '修改密码：原密码错误',
            // 			'-1005'=>'密码长度只能为6-16位',
            // 			'-1006'=>'密码只能含字母、数字',
            '-1007' => '新旧密码一致，修改失败',

            /*-1200用户身份信息校验*/
            '-1200' => '用户名不存在',
            '-1201' => '该用户注册后还未激活，请激活后再进行操作',
            '-1202' => '该用户已经注销，当前无法操作',
            '-1203' => '当前用户已经被冻结，无法继续操作',

            '-1208' => '系统繁忙,请重试',


            /*-1500用户名校验规则*/
            '-1500' => '请输入账户名',
            '-1501' => '用户名长度为2到18个字符',
            '-1502' => '用户名只能由汉字，字母，数字，下划线组成',
            '-1503' => '该账户已经存在',
            '-1504' => '该用户名未发生变动',
            '-1505' => '用户名已经被使用，请重新修改',
            '-1506' => '用户名不能使用纯数字',
            '-1507' => '用户名不能以数字开头',
            '-1510' => '用户名修改次数达到上限',


            /*-1600手机号校验规则*/
            '-1600' => '手机号不能为空',
            '-1601' => '手机号只能为11为数字',
            '-1607' => '输入的原手机号与实际不符',
            '-1608' => '输入的手机号与实际不符合',
            '-1609' => '新手机号已被使用',
            '-1610' => '该用户已经完成手机绑定',
            '-1611' => '该手机号已被使用',
            '-1612' => '请先绑定手机号后再进行修改',
            '-1613' => '国外手机只能为1到20位纯数字',


            /*账户信息操作*/
            '-1910' => '修改的实名信息未发生变化',
            '-1911' => '手机号为空，不能初始化密码',
            '-1912' => '密码已经被初始化',
            '-1913' => '邮箱不能为空',
            '-1914' => '联系方式未发生变动',

            '-9999' => '系统异常，操作失败',
            '0000' => '成功'
        );

        $code = array_key_exists($code, $cfg) ? $code : '-9999';
        $msg = isset($cfg[$code]) ? $cfg[$code] : '';
        return array('code' => $code, 'msg' => $msg);
    }
}
